package models

import (
	"encoding/json"
	"errors"
	"io/ioutil"
	"net/http"
	"regexp"
	"strconv"
	"strings"
)

type LocationRespHeader struct {
	Status    int    `json:"status"`
	TimeStamp int    `json:"time"`
	Version   string `json:"version"`
}

type LocationResponse struct {
	Response map[string]interface{} `json:"response"`
	RespHead LocationRespHeader     `json:"responseHeader"`
}

var regPhoneNumber *regexp.Regexp

func init() {
	var err error
	regPhoneNumber, err = regexp.Compile("^[0-9]*$")
	if err != nil {
		panic(err.Error())
	}
}

func IsValidPhoneNumber(n string) bool {
	if len(n) == 0 {
		return false
	}

	return regPhoneNumber.MatchString(n)
}

func GetOneLocation(number string) (string, error) {
	numArr := []string{number}
	retMap := make(map[string]string)

	err := requestOnceLocation(numArr, retMap)
	if err != nil {
		return "", err
	}

	return retMap[number], err
}

func requestOnceLocation(numbers []string, retMap map[string]string) error {
	if len(numbers) == 0 {
		return errors.New("have no any number")
	}

	request := `http://mobsec-dianhua.baidu.com/dianhua_api/open/location?tel=`
	for _, v := range numbers {
		request += v + ","
	}

	request = strings.TrimRight(request, ",")

	resp, err := http.Get(request)
	if err != nil {
		return err
	}

	defer resp.Body.Close()

	locationByte, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return err
	}

	if resp.StatusCode != http.StatusOK {
		return errors.New(resp.Status)
	}

	var locationData LocationResponse
	err = json.Unmarshal(locationByte, &locationData)
	if err != nil {
		return err
	}

	// check head return code
	if locationData.RespHead.Status != 200 {
		return errors.New("response code is not 200, but: " +
			strconv.Itoa(locationData.RespHead.Status))
	}

	if len(locationData.Response) == 0 {
		return errors.New("query succ but zero record")
	}

	for k, v := range locationData.Response {
		if v == nil {
			continue
		}
		node := v.(map[string]interface{})
		retMap[k] = node["location"].(string)
	}

	return err
}

func GetLocation(numbers []string) (map[string]string, error) {
	maxCount := 20
	allCount := len(numbers)
	beginPos := 0
	endPos := allCount
	var err error

	if allCount == 0 {
		return nil, errors.New("have none number")
	}

	retMap := make(map[string]string)

	if allCount > maxCount {
		for i := 0; i < (allCount / maxCount); i++ {
			beginPos = i * maxCount
			endPos = (i + 1) * maxCount
			err = requestOnceLocation(numbers[beginPos:endPos], retMap)
			if err != nil {
				return nil, err
			}
		}
		beginPos = endPos
		endPos = allCount
	}

	err = requestOnceLocation(numbers[beginPos:endPos], retMap)
	if err != nil {
		return nil, err
	}

	return retMap, err
}

// http://mobsec-dianhua.baidu.com/dianhua_api/open/location?tel=1866602562
/*
{"response":{
"1866602562":{"detail":{"area":[{"city":"广州"}],"province":"广东","type":"domestic","operator":"联通"},
"location":"广东广州联通"},
"13718351691":{"detail":{"area":[{"city":"北京"}],"province":"北京","type":"domestic","operator":"移动"},
"location":"北京北京移动"}},
"responseHeader":{"status":200,"time":1583638339816,"version":"1.1.0"}}
*/
